﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Text.Unicode;
using System.Threading.Tasks;
using DHM.IService;
using DHM.Model;
using DHM.WXMiniProgram.Utility.APIResult;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using SqlSugar;

namespace DHM.WXMiniProgram.Controllers {
    [Route ("api/[controller]")]
    [ApiController]
    [Authorize]
    public class UserCommentController : ControllerBase {
        private readonly IUserCommentService _userCommentService;
        private readonly IMemoryCache _memoryCache;
        private const string grant_type = "client_credential";
        private const string appid = "wx955eba094fc98a80";
        private const string secret = "22d22ea1d0232e816f01963b51249a9c";
        public UserCommentController (IUserCommentService userCommentService, IMemoryCache memoryCache) {
            _userCommentService = userCommentService;
            _memoryCache = memoryCache;
        }
        /// <summary>
        /// 根据当前模块获取用户评论
        /// </summary>
        /// <returns></returns>
        [HttpGet ("GetUserComments")]
        public async Task<IActionResult> GetUserComments (CommentModule commentModule) {
            var data = await _userCommentService.QueryAsync (x => x.CommentModule.Equals (commentModule));
            return Ok (data);
        }
        /// <summary>
        /// 获取用户评论，按时间倒序
        /// </summary>
        /// <param name="commentModule"></param>
        /// <param name="page"></param>
        /// <param name="size"></param>
        /// <param name="total"></param>
        /// <returns></returns>

        [HttpGet ("GetUserCommentsPage")]
        public async Task<IActionResult> GetUserCommentsPage (CommentModule commentModule, int page, int size, int total) {
            var data = await _userCommentService.QueryAsyncOrder (x => x.CommentModule.Equals (commentModule),
                y => y.CommentTime, OrderByType.Desc, page, size, total
            );

            return Ok (data);
        }
        /// <summary>
        /// 添加评论
        /// </summary>
        /// <param name="userComment"></param>
        /// <returns></returns>

        [HttpPost ("AddComment")]
        public async Task<APIResult> AddComment ([FromForm] UserComment userComment) {
            userComment.CommentTime = DateTime.Now;
            var result = await _userCommentService.AddAsync (userComment);

            if (result) {
                return APIResultHelper.Success (userComment);
            } else {
                return APIResultHelper.Error ("评论添加失败");
            }
        }
        /// <summary>
        /// 过滤评论
        /// </summary>
        /// <param name="contents"></param>
        /// <returns></returns>

        [HttpGet ("CommentFilter")]
        public async Task<APIResult> CommentFilter (string contents) {
            var ak = await GetAccessToken ();
            var url = $"https://api.weixin.qq.com/wxa/msg_sec_check?access_token={ak}";

            using (var httpclient = new HttpClient ()) {
                httpclient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

                var ct = JsonSerializer.Serialize (new { content = contents });

                var c = new StringContent (ct, Encoding.UTF8,"application/json");

                var response = await httpclient.PostAsync (url, c);

                var result = await response.Content.ReadAsStringAsync ();

                if (response.IsSuccessStatusCode) return APIResultHelper.Success (result);

                else return APIResultHelper.Error (response.StatusCode.ToString ());
            }
            //"特3456书yuuo莞6543李zxcz蒜7782法fgnv级"         
        }
        /// <summary>
        /// 获取AccessToken,默认从缓存中获取，2小时后过期，重新更新缓存
        /// </summary>
        /// <returns></returns>

        private async Task<string> GetAccessToken () {
            if (!_memoryCache.TryGetValue ("access_token", out string token)) {
                return await _memoryCache.GetOrCreate ("access_token", async (entry) => {
                    AccessToken ac = null;
                    using (var httpclient = new HttpClient ()) {

                        var token_str = await httpclient.GetStringAsync (

                            $"https://api.weixin.qq.com/cgi-bin/token?grant_type={grant_type}&appid={appid}&secret={secret}");

                        ac = JsonSerializer.Deserialize<AccessToken> (token_str);

                        entry.SetValue (ac.access_token);

                        entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds (ac.expires_in);

                        entry.RegisterPostEvictionCallback ((key, obj, reason, state) => {
                            if (reason == EvictionReason.Expired) {
                                _memoryCache.Remove ("access_token");
                            }
                        });
                    }

                    return ac.access_token;
                });
            } else {
                return _memoryCache.Get<string> ("access_token");
            }
        }

        [Serializable]
        public class AccessToken {
            public string access_token { get; set; }
            public int expires_in { get; set; }
        }
    }

}